home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-12-10 | 20.5 KB | 366 lines | [TEXT/gamI] |
- (##declare
- (multilisp)
- (extended-bindings)
- (not safe)
- (not autotouch)
- (block)
- (fixnum)
- (not intr-checks))
-
- ;------------------------------------------------------------------------------
-
- ; Utilities
-
- (define (mac#unsigned16->signed16 x) ; ##vector16-ref returns 0..65535
- (##fixnum.- (##fixnum.modulo (##fixnum.+ x 32768) 65536) 32768))
-
- ; Macintosh events
-
- (define (mac#event-what ev)
- (##vector16-ref ev 0))
- (define (mac#event-message ev)
- (##fixnum.+ (##fixnum.* (##vector16-ref ev 1) 65536) (##vector16-ref ev 2)))
- (define (mac#event-when ev)
- (##fixnum.+ (##fixnum.* (##vector16-ref ev 3) 65536) (##vector16-ref ev 4)))
- (define (mac#event-where ev)
- (mac#point (##vector16-ref ev 5) (##vector16-ref ev 6)))
- (define (mac#event-modifiers ev)
- (##vector16-ref ev 7))
-
- (define (mac#modifiers-button? modifiers)
- (##fixnum.zero? (##fixnum.logand modifiers 128)))
-
- (define (mac#modifiers-command? modifiers)
- (##not (##fixnum.zero? (##fixnum.logand modifiers 256))))
-
- (define (mac#modifiers-shift? modifiers)
- (##not (##fixnum.zero? (##fixnum.logand modifiers 512))))
-
- (define (mac#modifiers-alphalock? modifiers)
- (##not (##fixnum.zero? (##fixnum.logand modifiers 1024))))
-
- (define (mac#modifiers-option? modifiers)
- (##not (##fixnum.zero? (##fixnum.logand modifiers 2048))))
-
- ; Quickdraw points
-
- (define (mac#point v h)
- (let ((p (##make-vector16 2 0)))
- (##vector16-set! p 0 v)
- (##vector16-set! p 1 h)
- p))
-
- (define (mac#point-v r) (mac#unsigned16->signed16 (##vector16-ref r 0)))
- (define (mac#point-h r) (mac#unsigned16->signed16 (##vector16-ref r 1)))
- (define (mac#point-v-set! r x) (##vector16-set! r 0 x))
- (define (mac#point-h-set! r x) (##vector16-set! r 1 x))
-
- ; Quickdraw rectangles
-
- (define (mac#rect top left bottom right)
- (let ((r (##make-vector16 4 0)))
- (##vector16-set! r 0 top)
- (##vector16-set! r 1 left)
- (##vector16-set! r 2 bottom)
- (##vector16-set! r 3 right)
- r))
-
- (define (mac#rect-top r) (mac#unsigned16->signed16 (##vector16-ref r 0)))
- (define (mac#rect-left r) (mac#unsigned16->signed16 (##vector16-ref r 1)))
- (define (mac#rect-bottom r) (mac#unsigned16->signed16 (##vector16-ref r 2)))
- (define (mac#rect-right r) (mac#unsigned16->signed16 (##vector16-ref r 3)))
- (define (mac#rect-top-set! r x) (##vector16-set! r 0 x))
- (define (mac#rect-left-set! r x) (##vector16-set! r 1 x))
- (define (mac#rect-bottom-set! r x) (##vector16-set! r 2 x))
- (define (mac#rect-right-set! r x) (##vector16-set! r 3 x))
-
- ; Quickdraw procedures
-
- (define (mac#newwindow bounds title visible procid behind goaway)
- (mac_#newwindow bounds title visible procid behind goaway))
-
- (define (mac#getnewwindow windowid behind)
- (mac_#getnewwindow windowid behind))
-
- (define (mac#disposewindow w)
- (mac_#disposewindow w))
-
- (define (mac#selectwindow w)
- (mac_#selectwindow w))
-
- (define (mac#hidewindow w)
- (mac_#hidewindow w))
-
- (define (mac#showwindow w)
- (mac_#showwindow w))
-
- (define (mac#frontwindow)
- (mac_#frontwindow))
-
- (define (mac#findwindow pt w-cell)
- (mac_#findwindow pt w-cell))
-
- (define (mac#trackgoaway w pt)
- (mac_#trackgoaway w pt))
-
- (define (mac#dragwindow w pt r)
- (mac_#dragwindow w pt r))
-
- (define (mac#invalrect port r)
- (mac_#invalrect port r))
-
- (define (mac#beginupdate w)
- (mac_#beginupdate w))
-
- (define (mac#endupdate w)
- (mac_#endupdate w))
-
- (define (mac#openport port) (mac_#openport port))
- (define (mac#initport port) (mac_#initport port))
- (define (mac#closeport port) (mac_#closeport port))
- (define (mac#setport port) (mac_#setport port))
- (define (mac#getport) (mac_#getport))
- (define (mac#setorigin port h v) (mac_#setport port h v))
- (define (mac#backpat port pat) (mac_#backpat port pat))
- (define (mac#hidecursor) (mac_#hidecursor))
- (define (mac#showcursor) (mac_#showcursor))
- (define (mac#pensize port width height) (mac_#pensize port width height))
- (define (mac#penmode port mode) (mac_#penmode port mode))
- (define (mac#penpat port pat) (mac_#penpat port pat))
- (define (mac#pennormal port) (mac_#pennormal port))
- (define (mac#moveto port h v) (mac_#moveto port h v))
- (define (mac#move port dh dv) (mac_#move port dh dv))
- (define (mac#lineto port h v) (mac_#lineto port h v))
- (define (mac#line port dh dv) (mac_#line port dh dv))
- (define (mac#textfont port font) (mac_#textfont port font))
- (define (mac#textface port face) (mac_#textface port face))
- (define (mac#textmode port mode) (mac_#textmode port mode))
- (define (mac#textsize port size) (mac_#textsize port size))
- (define (mac#spaceextra port extra) (mac_#spaceextra port extra))
- (define (mac#drawchar port ch) (mac_#drawchar port ch))
- (define (mac#dr art and complete before the processing of the
- ; original event is finished.
- ;
- ; To solve this problem, this procedure is written so that it
- ; does not cons and does not allow interrupts (interrupt checks are
- ; not generated inside the procedure and no procedure which might check
- ; interrupts is called). To prevent consing this procedure mutates
- ; constants (this is OK in Gambit even though it is an error in IEEE-Scheme).
- ;
- ; In addition, each window has an associated queue of pending events.
- ; Only one event per window can be processed at a time. If an event is
- ; generated for a particular window and that window is still processing a
- ; previous event, the event is put on the window's queue. When the
- ; processing of an event ends, the next event on the queue is processed (if
- ; there is one). Unfortunately, this means that if the processing of an
- ; event is aborted (due to an error or user interrupt), the window will
- ; not accept any new events. The procedure call (mac#window-reset wind)
- ; can be used to reenable the processing of new events on the window 'wind'.
- ;
- ; The processing of a window's events is done in a task (created by a
- ; future). This means that multiple windows may be "running" concurrently
- ; with the main program. This introduces the usual multitasking problems.
- ; Shared data structures should be protected with semaphores to guarantee
- ; that only one task is accessing them at any given point in time.
-
- (let* ((what (##vector16-ref event 0))
- (message (##fixnum.+ (##fixnum.* (##vector16-ref event 1) 65536)
- (##vector16-ref event 2)))
- (w-cell '(0)) ; these two constants get mutated (to avoid consing)
- (where "1234"))
- (cond ((or (##fixnum.= what 1) ; mousedown event
- (##fixnum.= what 2)) ; mouseup event
- (##vector16-set! where 0 (##vector16-ref event 5)) ; mutate 'where'
- (##vector16-set! where 1 (##vector16-ref event 6))
- (let* ((in (mac#findwindow where w-cell)) ; mutate 'w-cell'
- (w (##car w-cell))
- (wind-struct (mac#window-lookup w)))
- (if wind-struct
- (cond ((##fixnum.= in 3) ; incontent
- (if (##fixnum.= w (mac#frontwindow))
- (begin
- (mac#globaltolocal w where)
- (##vector16-set! event 5 (##vector16-ref where 0))
- (##vector16-set! event 6 (##vector16-ref where 1))
- (mac#window-handle-event wind-struct event))
- (begin
- (if (##fixnum.= what 1) (mac#selectwindow w))
- #f)))
- ((##fixnum.= in 4) ; indrag
- (if (##fixnum.= what 1)
- (mac#dragwindow w where mac#window-drag-bounds))
- #f)
- ((##fixnum.= in 6) ; ingoaway
- (if (and (##fixnum.= what 1) (mac#trackgoaway w where))
- (begin
- (##vector16-set! event 0 0)
- (mac#window-handle-event wind-struct event))
- #f)))
- (##os-handle-event event))))
- ((or (##fixnum.= what 3) ; keydown event
- (##fixnum.= what 4) ; keyup event
- (##fixnum.= what 5)) ; autokey event
- (if (mac#modifiers-command? (##vector16-ref event 7)) ; command?
- (##os-handle-event event)
- (let* ((w (mac#frontwindow))
- (wind-struct (mac#window-lookup w)))
- (if wind-struct
- (mac#window-handle-event wind-struct event)
- (##os-handle-event event)))))
- ((##fixnum.= what 6) ; update event
- (let ((wind-struct (mac#window-lookup message)))
- (if wind-struct
- (begin
- (mac#beginupdate message) ; discard update region
- (mac#endupdate message)
- (mac#window-handle-event wind-struct event))
- (##os-handle-event event))))
- ((##fixnum.= what 8) ; activate and deactivate events
- (let ((wind-struct (mac#window-lookup message)))
- (if wind-struct
- (mac#window-handle-event wind-struct event)
- (##os-handle-event event))))
- (else
- (##os-handle-event event)))))
-
- (set! ##handle-os-event mac#event-handler)
-
- ;------------------------------------------------------------------------------
-
- ; Drawing window
-
- (define clear-graphics #f)
- (define position-pen #f)
- (define draw-line-to #f)
- (define draw-point #f)
- (define clear-point #f)
- (define graphics-text #f)
-
- (let ()
-
- (define top 40)
- (define right 510)
- (define y-max 200.) ; must be inexact (flonum)
- (define x-max 200.) ; " "
- (define scaling .5) ; " "
- (define visible? #f)
-
- (define (cx x)
- (##flonum.->fixnum
- (##flonum.* (##flonum.+ x-max (##real-part (##exact->inexact x)))
- scaling)))
-
- (define (cy y)
- (##flonum.->fixnum
- (##flonum.* (##flonum.- y-max (##real-part (##exact->inexact y)))
- scaling)))
-
- (let* ((clear-rect (mac#rect -32000 -32000 32000 32000))
- (width (##flonum.->fixnum (##flonum.* (##flonum.* 2. x-max) scaling)))
- (height (##flonum.->fixnum (##flonum.* (##flonum.* 2. y-max) scaling)))
- (w (mac#newwindow
- (mac#rect top (##fixnum.- right width) (##fixnum.+ top height) right)
- "Drawing" visible? 19 (if visible? -1 0) #t))
- (head (##cons #f '()))
- (tail head)
- (pen-x0 (cx 0))
- (pen-y0 (cy 0))
- (pen-x #f)
- (pen-y #f))
-
- (define (wind msg)
- (cond ((##eq? msg 'GOAWAY) goaway)
- ((##eq? msg 'UPDATE) update)
- (else ##list))) ; discard other events
-
- (define (goaway)
- (mac#hidewindow w))
-
- (define (update)
- (set! pen-x pen-x0)
- (set! pen-y pen-y0)
- (let loop ((l (##cdr head)))
- (if (##pair? l)
- (begin ((##car l)) (loop (##cdr l))))))
-
- (define (show)
- (if (##fixnum.zero? (mac#peek8 (##fixnum.+ w 110))) ; not visible?
- (begin
- (mac#showwindow w) ; make it visible
- (mac#selectwindow w)))) ; and in front of all other windows
-
- (define (clear)
- (##set-cdr! head '())
- (set! tail head)
- (mac#eraserect w clear-rect))
-
- (define (add action)
- (let ((x (##cons action '())))
- (##set-cdr! tail x)
- (set! tail x)
- (show)
- (action)))
-
- (define (init)
- (set! pen-x pen-x0)
- (set! pen-y pen-y0)
- (clear))
-
- (define (make-position-pen x y)
- (lambda ()
- (set! pen-x x)
- (set! pen-y y)))
-
- (define (make-draw-line-to x y)
- (lambda ()
- (mac#moveto w pen-x pen-y)
- (mac#lineto w x y)
- (set! pen-x x)
- (set! pen-y y)))
-
- (define (make-draw-point x y)
- (lambda ()
- (mac#moveto w x y)
- (mac#lineto w x y)))
-
- (define (make-clear-point x y)
- (lambda ()
- (mac#penmode w 11) ; patBic
- (mac#moveto w x y)
- (mac#lineto w x y)
- (mac#penmode w 8))) ; patCopy
-
- (define (make-graphics-text text x y)
- (lambda ()
- (mac#moveto w x y)
- (mac#drawstring w text)))
-
- (set! clear-graphics
- (lambda () (show) (clear) #f))
-
- (set! position-pen
- (lambda (x y) (add (make-position-pen (cx x) (cy y))) #f))
-
- (set! draw-line-to
- (lambda (x y) (add (make-draw-line-to (cx x) (cy y))) #f))
-
- (set! draw-point
- (lambda (x y) (add (make-draw-point (cx x) (cy y))) #f))
-
- (set! clear-point
- (lambda (x y) (add (make-clear-point (cx x) (cy y))) #f))
-
- (set! graphics-text
- (lambda (text x y)
- (if (##string? text) (add (make-graphics-text text (cx x) (cy y))))
- #f))
-
- (mac#textfont w 4) ; monaco
- (mac#textsize w 9)
-
- (init)
-
- (mac#window-bind w wind)))
-
- ;------------------------------------------------------------------------------
-